print('#############生成器，列表生成器#############')
g = (x * x for x in range(1, 11))
print(g)
print(next(g))
print(
    '#############generator保存的是算法，每次调用next(g)，就计算出g的下一个元素的值，直到计算到最后一个元素，没有更多的元素时，抛出StopIteration的错误。#############')
g1 = (x * x for x in range(1, 11))
for n in g1:
    print(n)
print('#############斐波拉契数，前两个数的和等于第三个数#############')


def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        temp = a  # 保存前一个数
        a = b  # 当前输出的数
        b = temp + b  # 下次输出的数
        n = n + 1


fib(8)
print('#############斐波拉契数，前两个数的和等于第三个数，a,b=b,a+b，v2#############')


def fib_v2(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1


fib_v2(8)
print('#############斐波拉契数，前两个数的和等于第三个数，a,b=b,a+b，v3#############')


def fib_v3(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'


for g in fib_v3(8):
    print(g)
print(
    '#############generator和函数的执行流程不一样。函数是顺序执行，遇到return语句或者最后一行函数语句就返回。#############')
print(
    '#############而变成generator的函数，在每次调用next()的时候执行，遇到yield语句返回，再次执行时从上次返回的yield语句处继续执行。#############')


def test_yield():
    print("第一步")
    yield 1
    print("第二步")
    yield 2
    print("第三步")
    yield 3


o = test_yield()
next(o)
next(o)
next(o)
print(
    '#############用for循环调用generator时，发现拿不到generator的return语句的返回值。如果想要拿到返回值，必须捕获StopIteration错误，返回值包含在StopIteration的value中#############')
g = fib_v3(6)
while True:
    try:
        x = next(g)
        print("g:", x)
    except StopIteration as e:
        print("'Generator return value:'" + e.value)
        break
print('#############输出杨辉三角#############')


def triangles():
    row = [1]
    while True:
        yield (row)
        row = [1] + [row[k] + row[k + 1] for k in range(len(row) - 1)] + [1]


n = 0
results = []
for t in triangles():
    print(t)
    results.append(t)
    n = n + 1
    if n == 10:
        break
